﻿// DiyToDo.cpp: 实现文件
//

#include "pch.h"
#include "LiWi.h"
#include "afxdialogex.h"
#include "DiyToDo.h"
#include "Data.h"
#include "liwishell.h"
#include <afx.h> // 包含 MFC 头文件
#include <iostream>

// DiyToDo 对话框

IMPLEMENT_DYNAMIC(DiyToDo, CDialogEx)

DiyToDo::DiyToDo(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DiyToDo, pParent)
{

}

DiyToDo::~DiyToDo()
{
}

void DiyToDo::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(DiyToDo, CDialogEx)
	ON_BN_CLICKED(IDC_AddDo, &DiyToDo::OnBnClickedAdddo)
	ON_BN_CLICKED(IDC_CommamdRun, &DiyToDo::OnBnClickedCommamdrun)
	ON_BN_CLICKED(IDC_ExecuteRun, &DiyToDo::OnBnClickedExecuterun)
END_MESSAGE_MAP()


// DiyToDo 消息处理程序


BOOL DiyToDo::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	GetDlgItem(IDC_Speed_6)->SetWindowTextW(_T("100"));
	GetDlgItem(IDC_Units_6)->SetWindowTextW(_T("100"));
	GetDlgItem(IDC_Accel_6)->SetWindowTextW(_T("1000"));
	GetDlgItem(IDC_Decel_6)->SetWindowTextW(_T("1000"));
	((CComboBox*)GetDlgItem(IDC_DoSelect))->AddString(_T("获取坐标"));
	((CComboBox*)GetDlgItem(IDC_DoSelect))->AddString(_T("运动集合"));
	((CComboBox*)GetDlgItem(IDC_DoSelect))->SetCurSel(0);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


void DiyToDo::OnBnClickedAdddo()
{
	// TODO: 在此添加控件通知处理程序代码
	int DoNum=((CComboBox*)GetDlgItem(IDC_DoSelect))->GetCurSel();
	GetDlgItem(IDC_DoWhat)->GetWindowTextW(m_DoWhat);
	if (DoNum==0)		//获取坐标
	{
		modeList.AddTail(0);
		m_DoWhat += ">>获取坐标\r\n";
		GetDlgItem(IDC_DoWhat)->SetWindowTextW(m_DoWhat);
	}
	else if (DoNum==1)
	{
		modeList.AddTail(1);
		m_DoWhat += ">>运动集合\r\n";
		GetDlgItem(IDC_DoWhat)->SetWindowTextW(m_DoWhat);
	}
}


void DiyToDo::OnBnClickedCommamdrun()
{
	// TODO: 在此添加控件通知处理程序代码
	CString atype, speed, accel, decel;
	GetDlgItem(IDC_Speed_6)->GetWindowTextW(speed);
	GetDlgItem(IDC_Units_6)->GetWindowTextW(atype);
	GetDlgItem(IDC_Accel_6)->GetWindowTextW(accel);
	GetDlgItem(IDC_Decel_6)->GetWindowTextW(decel);
	for (int i = 0; i < 4; i++)
	{
		PMC_SetAtype(Data::handle, i, _ttof(atype));
		PMC_SetSpeed(Data::handle, i, _ttof(speed));
		PMC_SetAccel(Data::handle, i, _ttof(accel));
		PMC_SetAccel(Data::handle, i, _ttof(decel));
	}
	startMode = 1;
	if (modeList.GetCount()>0)
	{
		int axis[2] = { 0,1 };
		float points[10] = { 0,0,0,100,100,100,100,0,0,0 };
		int otlist[5] = { 0,1,1,1,1 };
		for (POSITION pos = modeList.GetHeadPosition(); pos !=NULL;)
		{
			int value = modeList.GetNext(pos);
			if (value==0)
			{
				GetPos(startMode, 2);
			}
			else if (value==1)
			{
				MoveAbs(startMode, 5, 2, points, 5, otlist, 5000);

			}
		}
	}
	
}


void DiyToDo::OnBnClickedExecuterun()
{
	// TODO: 在此添加控件通知处理程序代码
	CString atype, speed, accel, decel;
	GetDlgItem(IDC_Speed_6)->GetWindowTextW(speed);
	GetDlgItem(IDC_Units_6)->GetWindowTextW(atype);
	GetDlgItem(IDC_Accel_6)->GetWindowTextW(accel);
	GetDlgItem(IDC_Decel_6)->GetWindowTextW(decel);
	for (int i = 0; i < 4; i++)
	{
		PMC_SetAtype(Data::handle, i, _ttof(atype));
		PMC_SetSpeed(Data::handle, i, _ttof(speed));
		PMC_SetAccel(Data::handle, i, _ttof(accel));
		PMC_SetAccel(Data::handle, i, _ttof(decel));
	}
	startMode = 2;
	if (modeList.GetCount() > 0)
	{
		int axis[2] = { 0,1 };
		float points[10] = { 0,0,0,100,100,100,100,0,0,0 };
		int otlist[5] = { 0,1,1,1,1 };
		for (POSITION pos = modeList.GetHeadPosition(); pos != NULL;)
		{
			int value = modeList.GetNext(pos);
			if (value == 0)
			{
				GetPos(startMode, 2);
			}
			else if (value == 1)
			{
				MoveAbs(startMode, 5, 2, points, 5, otlist, 5000);
			}
		}
	}
}

//分割
void DiyToDo::SplitString(const char* input, CList<CString>& output)
{
	// 清空输出数组
	//output.RemoveAll();
	// 将 char* 转换为 CString
	CString strInput(input);
	// 使用 \t 分割字符串
	int start = 0;
	int end = 0;
	while ((end = strInput.Find('\t', start)) != -1) {
		// 提取子字符串并添加到输出数组
		CString token = (strInput.Mid(start, end - start)).Trim();
		
		output.AddTail(token);
		start = end + 1;
	}
	// 添加最后一个子字符串
	//output.AddTail(strInput.Mid(start).Trim());
}


void DiyToDo::GetPos(int mode,int iaxisNum)		//获取点位
{
	char cmdbuff[2048];
	char tempbuff[2048];
	char cmdbuffAck[20480];
	//生成命令
	snprintf(cmdbuff, sizeof(cmdbuff), "?");	//生成对应命令的字符串
	//拼接DPOS
	for (int i = 0; i < iaxisNum; i++)
	{
		snprintf(tempbuff, sizeof(tempbuff), "DPOS(%d),", i);	//生成对应命令的字符串			
		strcat_s(cmdbuff, tempbuff);			//字符串拼接
		if (strlen(cmdbuff)>1000)
		{
			GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
			CTime currentTime = CTime::GetCurrentTime();
			m_DoLog += currentTime.Format(_T("%H:%M:%S  字符串拼接过长\r\n"));
			GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
			AfxMessageBox(_T("字符串拼接过长"));			
			return;
		}
	}
	GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
	CTime currentTime = CTime::GetCurrentTime();

	m_DoLog += currentTime.Format(_T("%H:%M:%S 当前指令为:\r\n")) ;
	m_DoLog += cmdbuff;
	m_DoLog += _T("\r\n");
	GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
	if (mode==1)
	{
		PMC_Command(Data::handle, cmdbuff, cmdbuffAck, 2048);
	}
	else if (mode==2)
	{
		PMC_Execute(Data::handle, cmdbuff, cmdbuffAck, 2048);
	}
	if (strlen(cmdbuffAck)==0)
	{
		GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
		CTime currentTime = CTime::GetCurrentTime();
		m_DoLog += currentTime.Format(_T("%H:%M:%S  返回字符串为空\r\n"));
		GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
	}
	else
	{
		CList<CString> pointlist;
		SplitString(cmdbuffAck, pointlist);
		int index = 0;
		for (POSITION pos = pointlist.GetHeadPosition(); pos!= nullptr; index++)
		{
			CString point = pointlist.GetNext(pos);
			GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
			CTime currentTime = CTime::GetCurrentTime();
			CString a;
			a.Format(_T("当前AXIS%d点位为：%s\r\n"),index,point);
			m_DoLog += currentTime.Format(_T("%H:%M:%S  ") + a);
			GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
		}
		//GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
		//CTime currentTime = CTime::GetCurrentTime();
		//CString a;
		//a.Format(_T("当前执行指令为：%d\r\n"), cmdbuff);
		//m_DoLog += currentTime.Format(_T("%H:%M:%S  ")+a);
		//GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
	}
}

//假设控制一个 XY 两轴平台，从坐标点（0,0）—>（100,0）（输出口 0 输出 50ms）
//—>（100,100）（输出口 0 输出 50ms）—>（0,100）（输出口 0 输出 50ms）—>（0,0）
//（输出口 0 输出 50ms）的轨迹，则可以通过自己封装，用一条函数，快速发送下去。
void DiyToDo::MoveAbs(int mode, int imoveLen, int iaxisNum, float fposlist[], int iout, int outlist[], int outtime) {
	char cmdbuff[2048], tempbuff[2048];
	char cmdbuffAck[20480];
	//读取剩余缓冲
	int iBuffLen = 0;
	PMC_GetRemain_LineBuffer(Data::handle, 0, &iBuffLen);
	if (iBuffLen<=imoveLen*2)
	{
		GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
		CTime currentTime = CTime::GetCurrentTime();
		m_DoLog += currentTime.Format(_T("%H:%M:%S  运动缓冲不足\r\n"));
		GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
	}
	//生成命令
	snprintf(cmdbuff, sizeof(cmdbuff), "BASE(");
	//拼接运动轴列表
	for (int i = 0; i < iaxisNum; i++)
	{
		if (i < iaxisNum - 1) {
			snprintf(tempbuff, sizeof(tempbuff), "%d,", i);	//生成对应命令的字符串
		}
		else
		{
			snprintf(tempbuff, sizeof(tempbuff), "%d)\r\n", i);
		}
		strcat_s(cmdbuff, tempbuff);	//字符串拼接
		if (strlen(cmdbuff)>1000)
		{
			GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
			CTime currentTime = CTime::GetCurrentTime();
			m_DoLog += currentTime.Format(_T("%H:%M:%S  参数错误，字符串拼接过长\r\n"));
			GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
		}
	}
	//拼接运动
	for (size_t i = 0; i < imoveLen; i++)
	{
		if (outlist[i]==0)	//没有OUT输出
		{
			strcat_s(cmdbuff, "MoveAbs(");
			snprintf(tempbuff, sizeof(tempbuff), "%.3f,%.3f)\r\n", fposlist[i * iaxisNum], fposlist[i * iaxisNum + 1]);	//生成对应字符串
			strcat_s(cmdbuff, tempbuff);
		}
		else if (outlist[i]==1)
		{
			strcat_s(cmdbuff, "MoveAbs(");
			snprintf(tempbuff, sizeof(tempbuff), "%.3f,%.3f)\r\n", fposlist[i * iaxisNum], fposlist[i * iaxisNum + 1]);
			strcat_s(cmdbuff, tempbuff);
			strcat_s(cmdbuff, "Move_op2(");
			snprintf(tempbuff, sizeof(tempbuff), "%d,%d,%d)\r\n", iout, 1, outtime);
			strcat_s(cmdbuff, tempbuff);
		}
		else
		{
			GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
			CTime currentTime = CTime::GetCurrentTime();
			m_DoLog += currentTime.Format(_T("%H:%M:%S  参数错误\r\n"));
			GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
		}
	}
	GetDlgItem(IDC_Log)->GetWindowTextW(m_DoLog);
	CTime currentTime = CTime::GetCurrentTime();
	m_DoLog += currentTime.Format(_T("%H:%M:%S 当前指令为:\r\n"));
	m_DoLog += cmdbuff;
	m_DoLog += _T("\r\n");
	GetDlgItem(IDC_Log)->SetWindowTextW(m_DoLog);
	if (mode==1)
	{
		PMC_Command(Data::handle, cmdbuff, cmdbuffAck, 2048);
	}
	else if (mode == 2)
	{
		PMC_Execute(Data::handle, cmdbuff, cmdbuffAck, 2048);
	}
}